/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package repository;

import beans.Produto;
import connection.ConnectionBD;
import interacesRepository.IRepositoryProduto;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sql.rowset.serial.SerialBlob;
import oracle.sql.BLOB;

/**
 *
 * @author dlvcpe
 */
public class RepositoryProduto implements IRepositoryProduto {

    private static RepositoryProduto instancia;

    public static RepositoryProduto getInstancia() {
        if (instancia == null) {
            instancia = new RepositoryProduto();
        }
        return instancia;
    }
    private byte[] Blob;

    @Override
    public void excluir(Produto produto) {

        try {
            Statement stmt = ConnectionBD.getInstance().createStatement();
            String linhaSQL = new String("delete from produto_tb where IDPRODUTO = '" + produto.getId() + "'");

//            if (Main.paramentros.getImprimirSQL() == 1) {
//                System.out.println(linhaSQL);
//            }

            stmt.execute(linhaSQL);

        } catch (SQLException ex) {
            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void alterar(Produto produto) {

        if (produto.getFoto() == null) {

            try {
                Statement stmt = ConnectionBD.getInstance().createStatement();
                String linhaSQL;
                int flag = 0;
                // flag caso a nested table seja null
//produto.getId();
//produto.getNome();
//produto.getMarca();
//produto.getPeso();
//produto.getUnidade();
 /*
                 * idproduto integer,
                 peso INTEGER,
                 nome VARCHAR2 (30),
                 marca VARCHAR2(40),
                 datavalidade DATE,
                 foto BLOB,
                 unidade unidade_tp_var
                 */
                linhaSQL = ("update produto_tb set idProduto = '" + produto.getId()
                        + "', peso = '" + produto.getPeso() + "', nome = '"
                        + produto.getNome() + "', marca = '" + produto.getMarca()
                        + "', datavalidade = '" + produto.getDatavalidade()
                        + "', composicao_produto = ");

//                Iterator i = produto.getProdutoComposicao().iterator();
//                int cont = 0;
//                String stringComposicao = new String();
//
//                if (!i.hasNext()) { // se for nulo a nested table
//                    stringComposicao = "null";
//
//                } else { //se nao for
//                    while (i.hasNext()) {
//                        if (cont > 0) {
//                            stringComposicao = stringComposicao + ", ";
//                        } else {
//                            stringComposicao = "tp_nt_composicao_produto(";
//                            flag = 1;
//
//                        }
//                        MateriaPrima mp = (MateriaPrima) i.next();
//                        stringComposicao = stringComposicao + "tp_composicao_produto((select REF(M) from tb_materia_prima M where M.id = '" + mp.getId() + "'), '" + mp.getEstoque().toString().replace(".", ",") + "')";
//                        cont++;
//
//                    }
//
//                    if (flag == 1) {
//                        stringComposicao = stringComposicao + ")"; // adicionar isso se nao for nulo
//                    }

//                }

                linhaSQL = linhaSQL + (" where referencia = '" + produto.getId() + "'");


//                if (Main.paramentros.getImprimirSQL() == 1) {
//                    System.out.println(linhaSQL);
//                }

                stmt.execute(linhaSQL);



            } catch (SQLException ex) {
                Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

//        } else {
//
//            try {
//                String linhaSQL = new String();
//                int flag = 0; // flag caso a nested table seja null
//
//                linhaSQL = ("update tb_produto set descricao = '" + produto.getDescricao() + "', tamanho = '" + produto.getTamanho() + "', unidade = '" + produto.getUnidade() + "', foto = ?, quantidade = '" + produto.getEstoque() + "', preco = '" + produto.getPreco().toString().replace(".", ",") + "', composicao_produto = ");
//
//                Iterator i = produto.getProdutoComposicao().iterator();
//                int cont = 0;
//                String stringComposicao = new String();
//
//                if (!i.hasNext()) { // se for nulo a nested table
//                    stringComposicao = "null";
//
//                } else { //se nao for
//                    while (i.hasNext()) {
//                        if (cont > 0) {
//                            stringComposicao = stringComposicao + ", ";
//                        } else {
//                            stringComposicao = "tp_nt_composicao_produto(";
//                            flag = 1;
//
//                        }
//                        MateriaPrima mp = (MateriaPrima) i.next();
//                        stringComposicao = stringComposicao + "tp_composicao_produto((select REF(M) from tb_materia_prima M where M.id = '" + mp.getId() + "'), '" + mp.getEstoque().toString().replace(".", ",") + "')";
//                        cont++;
//
//                    }
//
//                    if (flag == 1) {
//                        stringComposicao = stringComposicao + ")"; // adicionar isso se nao for nulo
//                    }
//
//                }
//
//                linhaSQL = linhaSQL + stringComposicao + (" where referencia = '" + produto.getReferencia() + "'");
//                if (Main.paramentros.getImprimirSQL() == 1) {
//                    System.out.println(linhaSQL);
//                }
//                PreparedStatement ps = BC.getInstance().prepareStatement(linhaSQL);
//                ps.setBytes(1, produto.getFoto());
//                ps.executeUpdate();
//                ps.close();
//
//            } catch (SQLException ex) {
//                Logger.getLogger(RepositorioProduto.class.getName()).log(Level.SEVERE, null, ex);
//            }
//
//
//        }
//
//    }
    public Collection consultarTodos() {
        List c = new ArrayList();

        try {
            Statement stmt = ConnectionBD.getInstance().createStatement();
            String linhaSQL = new String("select p.referencia, p.descricao, p.tamanho, p.unidade, p.quantidade, p.preco from tb_produto p");

//            if (Main.paramentros.getImprimirSQL() == 1) {
//                System.out.println(linhaSQL);
//            }


            ResultSet rs = stmt.executeQuery(linhaSQL);

//            while (rs.next()) {
//                Produto p = new Produto();
//                p.setReferencia((Integer.parseInt(rs.getObject(1).toString())));
//                p.setDescricao(rs.getObject(2).toString());
//                p.setTamanho(rs.getObject(3).toString());
//                p.setUnidade(rs.getObject(4).toString());
//                p.setEstoque((Integer.parseInt(rs.getObject(5).toString())));
//                p.setPreco(new BigDecimal(rs.getObject(6).toString()));
//
//                c.add(p);
//            }

        } catch (SQLException ex) {
            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
        }
        return c;
    }

    @Override
    public Produto consultarProdutoID(Integer id) {
        Produto p = new Produto();

        try {
            Statement stmt = ConnectionBD.getInstance().createStatement();
            String linhaSQL = new String("SELECT p.idproduto, p.peso, p.nome, p.marca, p.datavalidade, p.foto,p.preco, u.* "
                    + "FROM produto_tb p, TABLE(unidade) u "
                    + "WHERE p.idproduto =" + id);

//            if (Main.paramentros.getImprimirSQL() == 1) {
//                System.out.println(linhaSQL);
//            }

            ResultSet rs = stmt.executeQuery(linhaSQL);
            while (rs.next()) {
                p.setId((Integer.parseInt(rs.getObject(1).toString())));
                p.setPeso(Float.parseFloat(rs.getObject(2).toString()));
                p.setNome(rs.getObject(3).toString());
                p.setMarca(rs.getObject(4).toString());
                p.setDatavalidade(rs.getObject(4).toString());
                //p.setFoto(rs.getBytes(5));
                System.out.println("Ate aqui");
                p.setPreco((Integer.parseInt(rs.getObject(6).toString())));
                p.setUnidade(rs.getObject(7).toString());//Integer.parseInt(rs.getObject(7).toString()));
            }
        } catch (SQLException ex) {
            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
        }

        return p;

    }

    @Override
    public void inserir(Produto produto) {
        try {
//
            String linhaSQL = new String();
            linhaSQL = ("INSERT INTO produto_tb (idproduto, peso, nome, marca, datavalidade, foto, preco,unidade ) "
                    + "VALUES(" + produto.getId() + "," + produto.getPeso() + ",'"
                    + produto.getNome() + "','" + produto.getMarca() + "',to_date('" + produto.getDatavalidade() + "','DD/MM/YYYY'), EMPTY_BLOB()," + produto.getPreco() + " ,"
                    + "unidade_tp_var(unidade_tp('" + produto.getUnidade() + "')))");

//            linhaSQL = ("INSERT INTO produto_tb (idproduto, peso, nome, marca, datavalidade, foto, unidade, preco)"
//                    + "VALUES(" + produto.getId() + "," + produto.getPeso() + ",'" + produto.getNome() + "','" + produto.getMarca()
//                    + "',to_date('" + produto.getDatavalidade() + "','DD/MM/YYYY'), ? ,unidade_tp_var(unidade_tp('" + produto.getUnidade() + "'))," + produto.getPreco() + ")");
            PreparedStatement ps = ConnectionBD.getInstance().prepareStatement(linhaSQL);
//            ps.setBytes(1, produto.getFoto());
//            ps.executeUpdate();
            ps.execute(linhaSQL);
            // ps.close();
//            if (Main.paramentros.getImprimirSQL() == 1){
//                System.out.println(linhaSQL);
//            }

            linhaSQL = ("SELECT foto FROM produto_tb WHERE idproduto = " + produto.getId() + " FOR UPDATE");


            PreparedStatement ps2 = ConnectionBD.getInstance().prepareStatement(linhaSQL);
            ResultSet rset = ps2.executeQuery(linhaSQL);
            while (rset.next()) {
                Blob blob = rset.getBlob(1);
                File file = new File("C:\\\\Users\\\\Ronaldo\\\\Documents\\\\NetBeansProjects\\\\ProjetoBD\\\\src\\\\images\\\\Desert.jpg");
                byte[] bbuf = new byte[1024];
                InputStream bin = new FileInputStream(file);
                // Realiza o cast especifico para o driver Oracle
                OutputStream bout = ((BLOB) blob).getBinaryOutputStream();

                int bytesRead = 0;
                while ((bytesRead = bin.read(bbuf)) != -1) {
                    bout.write(bbuf, 0, bytesRead);
                }
            }
//            Blob blob = null;
////            ps.setBlob(1, blob);
//            ps.executeUpdate();
////            ps.execute();
//
//            String ins = "SELECT foto FROM produto_tb WHERE idproduto = " + produto.getId() + " FOR UPDATE";
//            PreparedStatement ps2 = ConnectionBD.getInstance().prepareStatement(ins);
////            ResultSet res = ps2.executeQuery(ins);
////            while (res.next()) {
////                blob = (Blob) res.getBlob(1);
//                byte[] bbuf = new byte[1024];
//                File file = new File("C:\\Users\\Ronaldo\\Documents\\NetBeansProjects\\ProjetoBD\\src\\images\\Desert.jpg");
//
//                InputStream bin = new FileInputStream(file);
//                System.out.println("File == " );
//                OutputStream bout = ((BLOB) blob).setBinaryStream(0);//getBinaryOutputStream();
//                int bytesRead = 0;
//                while ((bytesRead = bin.read(bbuf)) != -1) {
//                    bout.write(bbuf, 0, bytesRead);
//                }//
//
//                if (bout != null) {
//                    bout.close();
//                }
//
        } catch (SQLException ex) {
            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

//     public void inserir(Produto produto) {
//        try {
////
//            String linhaSQL = new String();
//            linhaSQL = ("INSERT INTO produto_tb (idproduto, peso, nome, marca, datavalidade, foto, unidade, preco)"
//                    + "VALUES(" + produto.getId() + "," + produto.getPeso() + ",'" + produto.getNome() + "','" + produto.getMarca()
//                    + "',to_date('" + produto.getDatavalidade() + "','DD/MM/YYYY'), ? ,unidade_tp_var(unidade_tp('" + produto.getUnidade() + "'))," + produto.getPreco() + ")");
//
////            if (Main.paramentros.getImprimirSQL() == 1){
////                System.out.println(linhaSQL);
////            }
//            System.out.println("Linha SQL Insert Produto ==> " + linhaSQL);
//            System.out.println("PRoduto Foto " + produto.getFoto());
//
//            PreparedStatement ps = ConnectionBD.getInstance().prepareStatement(linhaSQL);
//            ps.setBytes(1, produto.getFoto());
//            ps.executeUpdate();
//            ps.close();
//
//            }catch(SQLException ex) {
//                Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
//            }
//     } 
//
//    public void inserir(Produto produto) {
//        try {
//
//            String linhaSQL = new String();
////            linhaSQL = ("INSERT INTO produto_tb (idproduto, peso, nome, marca, datavalidade, foto, unidade, preco)"
////                    + "VALUES(" + produto.getId() + "," + produto.getPeso() + ",'" + produto.getNome() + "','" + produto.getMarca()
////                    + "',to_date('" + produto.getDatavalidade() + "','DD/MM/YYYY'), ? ,unidade_tp_var(unidade_tp('" + produto.getUnidade() + "'))," + produto.getPreco() + ")");
//
////            if (Main.paramentros.getImprimirSQL() == 1){
////                System.out.println(linhaSQL);
////            }
//            System.out.println("Linha SQL Insert Produto ==> " + linhaSQL);
//            System.out.println("PRoduto Foto " + produto.getFoto());
//
////            PreparedStatement ps = ConnectionBD.getInstance().prepareStatement(linhaSQL);
////            ps.setBytes(1, produto.getFoto());
////            ps.executeUpdate();
////            ps.close();
//
//            //PreparedStatement ps = ConnectionBD.getInstance().prepareStatement(linhaSQL);
//            Blob blob = null;
////            ps.setBlob(1, blob);
//            //ps.executeUpdate();
////            ps.execute();
//
//            String ins = "SELECT foto FROM produto_tb WHERE idproduto = " + produto.getId() + " FOR UPDATE";
//            PreparedStatement ps2 = ConnectionBD.getInstance().prepareStatement(ins);
//            ResultSet res = ps2.executeQuery(ins);
//            while (res.next()) {
//                blob = (Blob) res.getBlob(1);
//                byte[] bbuf = new byte[1024];
//                File file = new File("C:\\Users\\Ronaldo\\Documents\\NetBeansProjects\\ProjetoBD\\src\\images\\Desert.jpg");
//
//                InputStream bin = new FileInputStream(file);
//                System.out.println("File == " );
//                OutputStream bout = ((BLOB) blob).setBinaryStream(0);//getBinaryOutputStream();
//                int bytesRead = 0;
//                while ((bytesRead = bin.read(bbuf)) != -1) {
//                    bout.write(bbuf, 0, bytesRead);
//                }//
//
//                if (bout != null) {
//                    bout.close();
//                }
//
//            }
//
//// Realiza o cast especifico para o driver Oracle
//
//
//        } catch (SQLException ex) {
//            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (FileNotFoundException ex) {
//            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
//        } catch (IOException ex) {
//            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
//        }// end while
//
//
////            
////            ps.setBlob(1, blob);
//////            ps.setBytes(1, produto.getFoto());
////        System.out.println(">>Linha SQL Insert Produto ==> " + linhaSQL);
////
////        ps.executeUpdate();
////
////        ps.close();
//
////            
////            String ins  = "SELECT foto FROM arquivos WHERE id ="+ produto.getId()+ "FOR UPDATE";
////ps  = ConnectionBD.getInstance().prepareStatement(ins);
////            ResultSet rset = ps.executeQuery(ins);
////            //rset  = pstmt2.executeQuery(ins);
////            while( rset.next() ){
////            Blob blob   = rset.getBlob(1);
////            // filePath eh a String com o caminho do arquivo a ser gravado
////            
////            File file    = new File( "C:\\Users\\Ronaldo\\Documents\\NetBeansProjects\\ProjetoBD\\src\\images\\Desert.jpg" );
////            byte[] bbuf   = new byte[1024];
////            InputStream bin  = new FileInputStream( file );
////            // Realiza o cast especifico para o driver Oracle
////            OutputStream bout  = ((BLOB) blob).getBinaryOutputStream();
////            
////            int bytesRead   = 0;
////            while( (bytesRead = bin.read(bbuf))!=-1 ){
////            bout.write(bbuf, 0, bytesRead);
////            }//
////            
////            if( bout!=null ) bout.close();
////            
////            }// end while
////            ConnectionBD.getInstance().commit();
////            } catch (SQLException ex) {
////                Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
////            } catch (FileNotFoundException ex) {
////            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
////        } catch (IOException ex) {
////            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
////    }
////    catch (SQLException ex
////
////    
////        ) {
////            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
////    }
//    }

    /*    public Collection consultarDescricao(String descricao) {
     List c = new ArrayList();

     try {
     Statement stmt = ConnectionBD.getInstance().createStatement();
     String linhaSQL = new String("SELECT p.referencia, p.descricao, p.tamanho, p.unidade, p.quantidade, p.preco "
     + "FROM tb_produto p "
     + "WHERE p.descricao LIKE '"+ descricao +"%'");

     //            if (Main.paramentros.getImprimirSQL() == 1) {
     //                System.out.println(linhaSQL);
     //            }

     ResultSet rs = stmt.executeQuery(linhaSQL);

     while (rs.next()) {
     Produto p = new Produto();
     //                p.setReferencia((Integer.parseInt(rs.getObject(1).toString())));
     //                p.setDescricao(rs.getObject(2).toString());
     //                p.setTamanho(rs.getObject(3).toString());
     //                p.setUnidade(rs.getObject(4).toString());
     //                p.setEstoque((Integer.parseInt(rs.getObject(5).toString())));
     //                p.setPreco(new BigDecimal(rs.getObject(6).toString()));

     c.add(p);
     }

     } catch (SQLException ex) {
     Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
     }
     return c;

     }
     */
    @Override
    public Collection consultarnome(String nome) {
 List c = new ArrayList();
 Produto produto = new Produto();
        try {
            String linhaSQL = ("SELECT p.idproduto, p.peso, p.nome, p.marca, p.datavalidade, foto"
                    + "u.* "
                    + "FROM produto_tb p, TABLE(unidade) u"
                    + " WHERE p.idproduto = "+ produto.getId());

                  Statement stmt = ConnectionBD.getInstance().createStatement();

//            if (Main.paramentros.getImprimirSQL() == 1){
//                System.out.println(linhaSQL);
//            }

            ResultSet rs = stmt.executeQuery(linhaSQL);

            //CPF, IDFORNECEDOR, NOME, EMAIL, SEXO, RG 
            while (rs.next()) {
                Produto z = new Produto();
                z.setId(Integer.parseInt(rs.getObject(1).toString()));
                z.setPeso((Integer.parseInt(rs.getObject(2).toString())));

                z.setNome(rs.getObject(3).toString());
                z.setMarca(rs.getObject(4).toString());
                z.setDatavalidade(rs.getObject(5).toString());
//                z.setFoto((byte[]) rs.getObject(6));
                z.setFoto(rs.getBytes(6));
                z.setPreco((Integer.parseInt(rs.getObject(7).toString())));
                z.setUnidade(rs.getObject(8).toString());
                c.add(z);
            }

        } catch (SQLException ex) {
            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
        }
        return c;

    }

    @Override
    public Collection consultartodos() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public int totalCadastrados() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public BigDecimal consultarPrecoProduto(Integer id) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void alterarPrecoProduto(Integer id) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void alterarFotoProduto(byte[] foto) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
    
    public Produto consultaProdutoId(Integer id){
                        Produto z = new Produto();

        try {
            String linhaSQL = ("SELECT p.idproduto, p.peso, p.nome, p.marca, p.datavalidade, foto"
                    + "u.* "
                    + "FROM produto_tb p, TABLE(unidade) u"
                    + " WHERE p.idproduto = "+ id);

                  Statement stmt = ConnectionBD.getInstance().createStatement();

//            if (Main.paramentros.getImprimirSQL() == 1){
//                System.out.println(linhaSQL);
//            }

            ResultSet rs = stmt.executeQuery(linhaSQL);

            //CPF, IDFORNECEDOR, NOME, EMAIL, SEXO, RG 
            while (rs.next()) {
                z.setId(Integer.parseInt(rs.getObject(1).toString()));
                z.setPeso((Integer.parseInt(rs.getObject(2).toString())));

                z.setNome(rs.getObject(3).toString());
                z.setMarca(rs.getObject(4).toString());
                z.setDatavalidade(rs.getObject(5).toString());
//                z.setFoto((byte[]) rs.getObject(6));
                z.setFoto(rs.getBytes(6));
                z.setPreco(Integer.parseInt(rs.getObject(7).toString()));
                z.setUnidade(rs.getObject(8).toString());
               // c.add(z);
            }

        } catch (SQLException ex) {
            Logger.getLogger(RepositoryProduto.class.getName()).log(Level.SEVERE, null, ex);
        }
      return z;

    }

}
